home *** CD-ROM | disk | FTP | other *** search
/ QuickTime 2.0 Developer Kit / QuickTime 2.0 Developer Kit.iso / mac / MAC / Programming Stuff / Sample Code / Movie Toolbox / AddFrameToMovie / AddFrameToMovie.c next >
Encoding:
Text File  |  1994-12-06  |  13.1 KB  |  577 lines  |  [TEXT/MPS ]

  1. /*
  2.   File:            AddFrameToMovie.c
  3.   Contains:        Adding a Frame to the End of an Existing Movie.
  4.   Written by:    John Wang / DTS
  5.   Copyright:    © 1991-1994 by Apple Computer, Inc., all rights reserved.
  6.   Change History (most recent first):
  7.   <2>         12/4/94        khs        changed the format of the file to the new look and feel
  8.   <2>        x/x/94        JW        Fixed error where ind was assumed to be 0 based
  9.   rather than 1 based.  And, added code to update
  10.   movie rather than require a flatten movie for
  11.   saving the new edited movie.
  12.   <1>         12/2/94        JW        1.0 Completed
  13.   To Do:
  14. */
  15.  
  16.  
  17. // INCLUDES
  18. #include     <GestaltEqu.h>
  19. #include    <Segload.h>
  20. #include    <ToolUtils.h>
  21. #include    <Devices.h>
  22. #include    <Errors.h>
  23.  
  24. #include    <Movies.h>
  25.  
  26.  
  27. // DEFINES
  28. #define Gestalttest        0xA1AD
  29. #define NoTrap            0xA89F
  30.  
  31. #define    appleID            128            
  32. #define    appleMenu        0
  33. #define    aboutMeCommand    1
  34.  
  35. #define    fileID            129
  36. #define openCommand        1
  37. #define    flattenCommand    2
  38. #define closeCommand    3
  39. #define    quitCommand     5
  40.  
  41. #define    aboutMeDLOG        128
  42. #define    okButton        1
  43.  
  44. #define    MAXWINDOWS        5
  45.  
  46. // FUNCTION PROTOTYPES
  47. Movie GetMovieFromFile(void);
  48. OSErr PlayMovie(int index);
  49. short Flatten(int index);
  50. void showAboutMeDialog(void);
  51. void Init(void);
  52. void Finish(void);
  53. void DoOpenCommand(void);
  54. void DoFlattenCommand(void);
  55. void DoCloseCommand(void);
  56. void PlayMovies(void);
  57. void DoCommand(long mResult);
  58.  
  59.  
  60. // GLOBALS
  61. Boolean DoneFlag = false;
  62. MenuHandle mymenu0, mymenu1;
  63. Boolean playingMovie[MAXWINDOWS];
  64. Movie myMovie[MAXWINDOWS];
  65. WindowPtr myWindow[MAXWINDOWS];
  66. int startlocation;
  67.  
  68.  
  69. // FUNCTIONS
  70.  
  71. /*------------------------------------------------------*/
  72. /*    GetMovieFromFile().                                    */
  73. /*------------------------------------------------------*/
  74.  
  75. Movie GetMovieFromFile(void)
  76. {
  77.     OSErr err;
  78.     StandardFileReply reply;
  79.     Point where =
  80.     {
  81.         200,  50
  82.     };
  83.     SFTypeList types;
  84.     short movieResRefNum;
  85.     short actualResId;
  86.     Movie theMovie;
  87.     long i,
  88.      maxCompressionSize;
  89.     Track myVideoTrack;
  90.     Media myVideoMedia;
  91.     OSType myMediaType;
  92.     Boolean done = false;
  93.     GWorldPtr myGWorld;
  94.     Rect movieBounds;
  95.     GDHandle oldGDevice;
  96.     CGrafPtr oldPort;
  97.     Handle compressedData;
  98.     ImageDescriptionHandle imageDescH;
  99.     TimeValue sampleDuration;
  100.  
  101.     types[0] = 'MooV';
  102.     StandardGetFilePreview(nil, 1, types, &reply);
  103.     if (!reply.sfGood)
  104.         return ((Movie)0);
  105.  
  106.     err = OpenMovieFile(&reply.sfFile, &movieResRefNum, fsWrPerm);
  107.     if (GetMoviesError())
  108.         return ((Movie)0);
  109.     if (err)
  110.         return ((Movie)0);
  111.     actualResId = 0;
  112.  
  113.     err = NewMovieFromFile(&theMovie, movieResRefNum, &actualResId, 
  114.                             (StringPtr)0, newMovieActive, (Boolean *)0);
  115.     if (GetMoviesError())
  116.         return ((Movie)0);
  117.     if (err)
  118.         return ((Movie)0);
  119.  
  120.     /*    This is where I add a frame to the end of the movie's video track.    */
  121.  
  122.     for (i = 1; ((i <= GetMovieTrackCount(theMovie)) && (!done)); i++)
  123.     {
  124.         myVideoTrack = GetMovieIndTrack(theMovie, i);
  125.         myVideoMedia = GetTrackMedia(myVideoTrack);
  126.         GetMediaHandlerDescription(myVideoMedia, &myMediaType, nil, nil);
  127.         if (myMediaType == VideoMediaType)
  128.             done = true;
  129.     }
  130.     if (done == false)
  131.         DebugStr("\pMovie contains no video tracks.");
  132.     else
  133.     {
  134.         if (BeginMediaEdits(myVideoMedia))
  135.             DebugStr("\pBeginMediaEdits failed.");
  136.  
  137.         GetMovieBox(theMovie, &movieBounds);
  138.         if (NewGWorld(&myGWorld, 1, &movieBounds, nil, nil, 0))
  139.             DebugStr("\pNewGWorld failed.");
  140.         GetGWorld(&oldPort, &oldGDevice);
  141.         SetGWorld(myGWorld, nil);
  142.         LockPixels(GetGWorldPixMap(myGWorld));
  143.         EraseRect(&movieBounds);
  144.         MoveTo(10, 10);
  145.         DrawString("\pHi there, John!!!");
  146.         imageDescH = (ImageDescriptionHandle)NewHandle(4);
  147.  
  148.         if (GetMaxCompressionSize(GetGWorldPixMap(myGWorld), &movieBounds, 1, 
  149.                                         codecNormalQuality, 'raw ', anyCodec, &maxCompressionSize))
  150.             DebugStr("\pCompressImage.");
  151.         compressedData = NewHandle(maxCompressionSize);
  152.         if (compressedData == nil)
  153.             DebugStr("\pCould not allocate compressedData block");
  154.         MoveHHi(compressedData);
  155.         HLock(compressedData);
  156.         if (CompressImage(GetGWorldPixMap(myGWorld), &movieBounds, codecNormalQuality, 
  157.                                 'raw ', imageDescH, StripAddress(*compressedData)))
  158.             DebugStr("\pCompressImage.");
  159.  
  160.         if (AddMediaSample(myVideoMedia, compressedData, 0, (**imageDescH).dataSize, 
  161.                             GetMediaTimeScale(myVideoMedia), (SampleDescriptionHandle)imageDescH, 
  162.                             1, 0, &sampleDuration))
  163.             DebugStr("\pInsertMediaIntoTracks.");
  164.  
  165.         if (InsertMediaIntoTrack(myVideoTrack, GetTrackDuration(myVideoTrack), sampleDuration, 
  166.                                     GetMediaTimeScale(myVideoMedia), 0x00010000))
  167.             DebugStr("\pInsertMediaIntoTracks.");
  168.  
  169.         if (EndMediaEdits(myVideoMedia))
  170.             DebugStr("\pEndMediaEdits failed.");
  171.         SetGWorld(oldPort, oldGDevice);
  172.         HUnlock(compressedData);
  173.         DisposeGWorld(myGWorld);
  174.         DisposeHandle(compressedData);
  175.         DisposeHandle((Handle)imageDescH);
  176.     }
  177.  
  178.     err = UpdateMovieResource(theMovie, movieResRefNum, actualResId, nil);
  179.     if (err != noErr)
  180.         DebugStr("\pUpdateResource failed.");
  181.  
  182.     /*    This is the end of the code for adding the one frame to the movie.    */
  183.  
  184.     err = CloseMovieFile(movieResRefNum);
  185.     if (GetMoviesError())
  186.         return ((Movie)0);
  187.     if (err)
  188.         return ((Movie)0);
  189.  
  190.     return (theMovie);
  191. }
  192.  
  193. /*------------------------------------------------------*/
  194. /*    PlayMovie().                                            */
  195. /*------------------------------------------------------*/
  196.  
  197. OSErr PlayMovie(int index)
  198. {
  199.     Rect movieBounds;
  200.  
  201.     GetMovieBox(myMovie[index], &movieBounds);
  202.     OffsetRect(&movieBounds, -movieBounds.left, -movieBounds.top);
  203.     if (movieBounds.right < 40)
  204.         movieBounds.right = 40;
  205.     if (movieBounds.bottom < 20)
  206.         movieBounds.bottom = 20;
  207.     SetMovieBox(myMovie[index], &movieBounds);
  208.     OffsetRect(&movieBounds, startlocation, startlocation);
  209.     myWindow[index] = NewCWindow(0L, &movieBounds, "\pMovie!", 1, 0, 
  210.                                     (WindowPtr) - 1, true, 0L);
  211.     startlocation += 50;
  212.     if (startlocation > 300)
  213.         startlocation = 50;
  214.  
  215.     SetMovieGWorld(myMovie[index], (CGrafPtr)myWindow[index], 0);
  216.     if (GetMoviesError())
  217.         DebugStr("\pSetMovieGWorld error.");
  218.  
  219.     /*    Uncomment these lines if you want to pre load the movie into ram.
  220.       GotoBeginningOfMovie(myMovie[index]);
  221.       if (LoadMovieIntoRam(myMovie[index], GetMovieTime(myMovie[index], 0L),
  222.       GetMovieDuration(myMovie[index]),
  223.       0) != noErr)
  224.       DebugStr("\pNot enough memory to load movie into ram.");
  225.     */
  226.     SetMovieRate(myMovie[index], 0x00010000);
  227.  
  228.     return noErr;
  229. }
  230.  
  231. /*------------------------------------------------------*/
  232. /*    Flatten().                                            */
  233. /*------------------------------------------------------*/
  234.  
  235. short Flatten(int index)
  236. {
  237.     StandardFileReply reply;
  238.     OSErr theErr = noErr;
  239.  
  240.     StandardPutFile("\pName of Flattened movie.", "\pUntitled", &reply);
  241.     if (!reply.sfGood)
  242.         return fnOpnErr;
  243.  
  244.     theErr = GetMoviesError();
  245.     if (theErr != noErr)
  246.         DebugStr("\pCall Before FlattenMovies failed.");
  247.  
  248.     FlattenMovie(myMovie[index], flattenAddMovieToDataFork, &reply.sfFile, 
  249.                         'TWOD', 0, createMovieFileDeleteCurFile, nil, nil);
  250.  
  251.     theErr = GetMoviesError();
  252.     if (theErr != noErr)
  253.         DebugStr("\pFlattenMovies failed.");
  254.  
  255.     return (theErr);
  256. }
  257.  
  258. /*------------------------------------------------------*/
  259. /*    showAboutMeDialog()                                    */
  260. /*------------------------------------------------------*/
  261.  
  262. void showAboutMeDialog(void)
  263. {
  264.     GrafPtr savePort;
  265.     DialogPtr theDialog;
  266.     short itemHit;
  267.  
  268.     GetPort(&savePort);
  269.     theDialog = GetNewDialog(aboutMeDLOG, nil, (WindowPtr) - 1);
  270.     SetPort(theDialog);
  271.  
  272.     do
  273.     {
  274.         ModalDialog(nil, &itemHit);
  275.     } while (itemHit != okButton);
  276.  
  277.     CloseDialog(theDialog);
  278.  
  279.     SetPort(savePort);
  280.     return;
  281. }
  282.  
  283. /*------------------------------------------------------*/
  284. /*    Init().                                                */
  285. /*------------------------------------------------------*/
  286.  
  287. void Init(void)
  288. {
  289.     OSErr err;
  290.     int i;
  291.     long QDfeature,
  292.      OSfeature;
  293.  
  294.     /*    Initialize Managaer.    */
  295.     InitGraf(&qd.thePort);
  296.     FlushEvents(everyEvent, 0);
  297.     InitWindows();
  298.     InitDialogs(nil);
  299.     InitCursor();
  300.  
  301.     /*    Set up menus.    */
  302.     mymenu0 = GetMenu(appleID);
  303.     AddResMenu(mymenu0, 'DRVR');
  304.     InsertMenu(mymenu0, 0);
  305.     mymenu1 = GetMenu(fileID);
  306.     InsertMenu(mymenu1, 0);
  307.     DrawMenuBar();
  308.  
  309.     /*    Set up variables.    */
  310.     startlocation = 50;
  311.     for (i = 0; i < MAXWINDOWS; i++)
  312.     {
  313.         playingMovie[i] = false;
  314.         myWindow[i] = nil;
  315.     }
  316.  
  317.     /*    Use Gestalt to find if QuickDraw and QuickTime is available.    */
  318.     if ((GetTrapAddress(Gestalttest) != GetTrapAddress(NoTrap)))
  319.     {
  320.         err = Gestalt(gestaltQuickdrawVersion, &QDfeature);
  321.         if (err)
  322.             ExitToShell();
  323.         err = Gestalt(gestaltSystemVersion, &OSfeature);
  324.         if (err)
  325.             ExitToShell();
  326.         if (!DoneFlag && (QDfeature & 0x0f00) != 0x0200 && OSfeature < 0x0607)
  327.             ExitToShell();
  328.         err = Gestalt(gestaltQuickTime, &QDfeature);
  329.         if (err)
  330.             ExitToShell();
  331.     }
  332.     else
  333.         ExitToShell();
  334.  
  335.     /*    Open QuickTime last.    */
  336.     err = EnterMovies();
  337.     if (err)
  338.         ExitToShell();
  339. }
  340.  
  341. /*------------------------------------------------------*/
  342. /*    Finish().                                            */
  343. /*------------------------------------------------------*/
  344.  
  345. void Finish(void)
  346. {
  347.     ExitMovies();
  348.     ExitToShell();
  349. }
  350.  
  351. /*------------------------------------------------------*/
  352. /*    DoOpenCommand().                                        */
  353. /*------------------------------------------------------*/
  354.  
  355. void DoOpenCommand(void)
  356. {
  357.     int i,
  358.      useThisIndex;
  359.  
  360.     useThisIndex = -1;
  361.  
  362.     /*    Search for the first window that is nil.    */
  363.     for (i = MAXWINDOWS - 1; i >= 0; i--)
  364.         if (myWindow[i] == nil)
  365.             useThisIndex = i;
  366.  
  367.         /*    If index = -1, then it means that there are no windows avaiable.    */
  368.     if (useThisIndex != -1)
  369.     {
  370.         myMovie[useThisIndex] = GetMovieFromFile();
  371.         if (myMovie[useThisIndex] != 0)
  372.         {
  373.             PlayMovie(useThisIndex);
  374.             playingMovie[useThisIndex] = true;
  375.         }
  376.     }
  377. }
  378.  
  379. /*------------------------------------------------------*/
  380. /*    DoFlattenCommand().                                        */
  381. /*------------------------------------------------------*/
  382.  
  383. void DoFlattenCommand(void)
  384. {
  385.     int i;
  386.     WindowPtr myTempWindow;
  387.  
  388.     /*    Flatten movie that is currently selected.    */
  389.     myTempWindow = FrontWindow();
  390.     if (myTempWindow == nil)
  391.         return;
  392.     for (i = 0; i < MAXWINDOWS; i++)
  393.         if (myWindow[i] == myTempWindow)
  394.             Flatten(i);
  395. }
  396.  
  397. /*------------------------------------------------------*/
  398. /*    DoCloseCommand().                                        */
  399. /*------------------------------------------------------*/
  400.  
  401. void DoCloseCommand(void)
  402. {
  403.     int i;
  404.     WindowPtr myTempWindow;
  405.  
  406.     /*    Close selected window.    */
  407.     myTempWindow = FrontWindow();
  408.     if (myTempWindow == nil)
  409.         return;
  410.     for (i = 0; i < MAXWINDOWS; i++)
  411.         if (myWindow[i] == myTempWindow)
  412.         {
  413.             DisposeMovie(myMovie[i]);
  414.             DisposeWindow(myTempWindow);
  415.             playingMovie[i] = false;
  416.             myWindow[i] = nil;
  417.         }
  418. }
  419.  
  420. /*------------------------------------------------------*/
  421. /*    DoCommand().                                        */
  422. /*------------------------------------------------------*/
  423.  
  424. void DoCommand(long mResult)
  425. {
  426.     int theMenu,
  427.      theItem;
  428.     Str255 daName;
  429.     GrafPtr savePort;
  430.  
  431.     theItem = LoWord(mResult);
  432.     theMenu = HiWord(mResult);
  433.  
  434.     switch (theMenu)
  435.     {
  436.         case appleID:
  437.             if (theItem == aboutMeCommand)
  438.                 showAboutMeDialog();
  439.             else
  440.             {
  441.                 GetMenuItemText(mymenu0, theItem, daName);
  442.                 GetPort(&savePort);
  443.                 (void)OpenDeskAcc(daName);
  444.                 SetPort(savePort);
  445.             }
  446.             break;
  447.  
  448.         case fileID:
  449.             switch (theItem)
  450.             {
  451.                 case openCommand:
  452.                     DoOpenCommand();
  453.                     break;
  454.                 case flattenCommand:
  455.                     DoFlattenCommand();
  456.                     break;
  457.                 case closeCommand:
  458.                     DoCloseCommand();
  459.                     break;
  460.                 case quitCommand:
  461.                     DoneFlag = true;
  462.                     break;
  463.                 default:
  464.                     break;
  465.             }
  466.             break;
  467.     }
  468.     HiliteMenu(0);
  469.     return;
  470. }
  471.  
  472. /*------------------------------------------------------*/
  473. /*    PlayMovies().                                            */
  474. /*------------------------------------------------------*/
  475.  
  476. void PlayMovies(void)
  477. {
  478.     int i;
  479.  
  480.     for (i = 0; i < MAXWINDOWS; i++)
  481.         if (playingMovie[i] == true)
  482.         {
  483.             if (IsMovieDone(myMovie[i]) == false)
  484.                 MoviesTask(myMovie[i], DoTheRightThing);
  485.         }
  486. }
  487.  
  488. /*------------------------------------------------------*/
  489. /*    main().                                                */
  490. /*------------------------------------------------------*/
  491.  
  492. main()
  493. {
  494.     int i;
  495.     char key;
  496.     Boolean track;
  497.     EventRecord myEvent;
  498.     WindowPtr whichWindow;
  499.     int yieldTime;
  500.  
  501.  
  502.     Init();
  503.     yieldTime = 0;
  504.     for (;;)
  505.     {
  506.  
  507.         /*    We can't just do ExitToShell because we must cann ExitMovies.    */
  508.         if (DoneFlag)
  509.             Finish();
  510.  
  511.         /*    Play movies which are active.    */
  512.         PlayMovies();
  513.  
  514.         if (WaitNextEvent(everyEvent, &myEvent, yieldTime, nil))
  515.         {
  516.             switch (myEvent.what)
  517.             {
  518.                 case mouseDown:
  519.                     switch (FindWindow(myEvent.where, &whichWindow))
  520.                     {
  521.                         case inSysWindow:
  522.                             SystemClick(&myEvent, whichWindow);
  523.                             break;
  524.                         case inMenuBar:
  525.                             DoCommand(MenuSelect(myEvent.where));
  526.                             break;
  527.                         case inContent:
  528.                             SelectWindow(whichWindow);
  529.                             break;
  530.                         case inDrag:
  531.                             DragWindow(whichWindow, myEvent.where, &qd.screenBits.bounds);
  532.                             break;
  533.                         case inGrow:
  534.                             break;
  535.                         case inGoAway:
  536.                             track = TrackGoAway(whichWindow, myEvent.where);
  537.                             if (track)
  538.                                 DoCloseCommand();
  539.                             break;
  540.                         case inZoomIn:
  541.                             break;
  542.                         case inZoomOut:
  543.                             break;
  544.                         default:
  545.                             break;
  546.                     }
  547.                     break;
  548.                 case keyDown:
  549.                 case autoKey:
  550.                     key = myEvent.message & charCodeMask;
  551.                     if (myEvent.modifiers & cmdKey)
  552.                         if (myEvent.what == keyDown)
  553.                             DoCommand(MenuKey(key));
  554.                     break;
  555.                 case updateEvt:
  556.                     for (i = 0; i < MAXWINDOWS; i++)
  557.                         if ((WindowPtr)myEvent.message == myWindow[i])
  558.                         {
  559.                             BeginUpdate((WindowPtr)myWindow[i]);
  560.                             EndUpdate((WindowPtr)myWindow[i]);
  561.                         }
  562.                     break;
  563.                 case diskEvt:
  564.                     break;
  565.                 case activateEvt:
  566.                     break;
  567.                 case app4Evt:
  568.                     break;
  569.                 default:
  570.                     break;
  571.             }
  572.         }
  573.     }
  574. }
  575.  
  576.  
  577.